package com.retail.shop.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.retail.core.entity.enums.DelFlagEnum;
import com.retail.core.entity.enums.StatusFlagEnum;
import com.retail.core.entity.result.Result;
import com.retail.douyin.entity.po.TokTikAppParamRequest;
import com.retail.douyin.service.AccessTokenService;
import com.retail.shop.entity.request.RetailAdminShopRequest;
import com.retail.shop.entity.vo.RetailAdminShopVo;
import com.retail.shop.entity.vo.RetailShopVo;
import com.retail.core.entity.ParamReq;
import com.retail.shop.entity.request.RetailShopRequest;
import com.retail.shop.entity.vo.ShopCardVo;
import com.retail.shop.entity.vo.ShopTypeStasticVo;
import com.retail.shop.enums.ExamineVerifyEnums;
import com.retail.shop.enums.ShopSourceEnums;
import com.retail.shop.mapper.RetailAdminShopMapper;
import com.retail.shop.mapper.RetailShopMapper;
import com.retail.shop.mapper.ShopCardMapper;
import com.retail.shop.service.RetailShopService;
import com.retail.system.entity.vo.AdminVo;
import com.retail.system.mapper.AdminMapper;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 商户信息 Service impl
 *
 * @author Administrator
 */
@Service
public class RetailShopServiceImpl implements RetailShopService {

    @Resource
    private RetailShopMapper retailShopMapper;


    @Resource
    private RetailAdminShopMapper retailAdminShopMapper;

    @Resource
    private AdminMapper adminMapper;

    @Override
    public RetailShopVo getModel(Long id) {
        RetailShopVo shopVo = retailShopMapper.getModel(id);
        shopVo.setShopSourceName(ShopSourceEnums.getStatusValues(shopVo.getShopSource()));
        AdminVo adminVo = adminMapper.getModelByPoiId(shopVo.getPoiId());
        if (ObjectUtil.isNotEmpty(adminVo)) {
            shopVo.setAdminId(adminVo.getId());
            shopVo.setAdminName(adminVo.getName());

            RetailAdminShopVo retailAdminShopVo = retailAdminShopMapper.getModelByAdminIdAndShopId(adminVo.getId(), shopVo.getId());
            if (ObjectUtil.isNotEmpty(retailAdminShopVo)) {
                shopVo.setExamineVerify(retailAdminShopVo.getExamineVerify());
                shopVo.setExamineVerifyName(ExamineVerifyEnums.getStatusValues(shopVo.getExamineVerify()));
            }
        }

        if (ObjectUtil.isNotEmpty(shopVo.getOwnerId())) {
            AdminVo ownerUser = adminMapper.getModel(shopVo.getOwnerId());
            if (ObjectUtil.isNotEmpty(ownerUser)) {
                shopVo.setOwnerUserName(ownerUser.getUsername());
                shopVo.setOwnerName(ownerUser.getName());
            }
        }

        if (ObjectUtil.isNotEmpty(shopVo.getSanitaryLicensePhoto())) {
            shopVo.setSanitaryLicensePhotos(Arrays.stream(shopVo.getSanitaryLicensePhoto().split(",")).collect(Collectors.toList()));
        }

        if (ObjectUtil.isNotEmpty(shopVo.getBusinessLicensePhoto())) {
            shopVo.setBusinessLicensePhotos(Arrays.stream(shopVo.getBusinessLicensePhoto().split(",")).collect(Collectors.toList()));
        }

        if (ObjectUtil.isNotEmpty(shopVo.getCorporationPhoto())) {
            shopVo.setCorporationPhotos(Arrays.stream(shopVo.getCorporationPhoto().split(",")).collect(Collectors.toList()));
        }

        if (ObjectUtil.isNotEmpty(shopVo.getDoorPhoto())) {
            shopVo.setDoorPhotos(Arrays.stream(shopVo.getDoorPhoto().split(",")).collect(Collectors.toList()));
        }

        if (ObjectUtil.isNotEmpty(shopVo.getEvnPhoto())) {
            shopVo.setEvnPhotos(Arrays.stream(shopVo.getEvnPhoto().split(",")).collect(Collectors.toList()));
        }

        if (ObjectUtil.isNotEmpty(shopVo.getDouyinPhoto())) {
            shopVo.setDouyinPhotos(Arrays.stream(shopVo.getDouyinPhoto().split(",")).collect(Collectors.toList()));
        }

        return shopVo;
    }

    @CacheEvict(value = "RETAIL_SHOP_POI_ID", key = "#request.poiId")
    @Transactional
    @Override
    public Long save(RetailShopRequest retailShopRequest) {
        retailShopMapper.save(retailShopRequest);
        return retailShopRequest.getId();
    }
    
    @CacheEvict(value = "RETAIL_SHOP_POI_ID", key = "#request.poiId")
    @Transactional
    @Override
    public Long update(RetailShopRequest request) {
        retailShopMapper.update(request);
        return request.getId();
    }

    @Override
    public List<RetailShopVo> listPage(ParamReq<RetailShopRequest> params) {
        params.setStartIndex((params.getCurrent() - 1) * params.getSize());
        List<RetailShopVo> ret = retailShopMapper.listPage(params);
        ret.forEach(r -> {
            r.setShopSourceName(ShopSourceEnums.getStatusValues(r.getShopSource()));

            if (ObjectUtil.isNotEmpty(r.getPoiId())) {
                AdminVo adminVo = adminMapper.getModelByPoiId(r.getPoiId());
                if (ObjectUtil.isNotEmpty(adminVo)) {
                    r.setAdminId(adminVo.getId());
                    r.setAdminName(adminVo.getName());

                    RetailAdminShopVo retailAdminShopVo = retailAdminShopMapper.getModelByAdminIdAndShopId(adminVo.getId(), r.getId());
                    if (ObjectUtil.isNotEmpty(retailAdminShopVo)) {
                        r.setExamineVerify(retailAdminShopVo.getExamineVerify());
                        r.setExamineVerifyName(ExamineVerifyEnums.getStatusValues(r.getExamineVerify()));
                    }
                }
            }

            if (ObjectUtil.isNotEmpty(r.getOwnerId())) {
                AdminVo ownerUser = adminMapper.getModel(r.getOwnerId());
                if (ObjectUtil.isNotEmpty(ownerUser)) {
                    r.setOwnerUserName(ownerUser.getUsername());
                    r.setOwnerName(ownerUser.getName());
                }
            }

            if (ObjectUtil.isNotEmpty(r.getSanitaryLicensePhoto())) {
                r.setSanitaryLicensePhotos(Arrays.stream(r.getSanitaryLicensePhoto().split(",")).collect(Collectors.toList()));
            } else {
                r.setSanitaryLicensePhotos(new ArrayList<>());
            }

            if (ObjectUtil.isNotEmpty(r.getBusinessLicensePhoto())) {
                r.setBusinessLicensePhotos(Arrays.stream(r.getBusinessLicensePhoto().split(",")).collect(Collectors.toList()));
            } else {
                r.setBusinessLicensePhotos(new ArrayList<>());
            }

            if (ObjectUtil.isNotEmpty(r.getCorporationPhoto())) {
                r.setCorporationPhotos(Arrays.stream(r.getCorporationPhoto().split(",")).collect(Collectors.toList()));
            } else {
                r.setCorporationPhotos(new ArrayList<>());
            }

            if (ObjectUtil.isNotEmpty(r.getDoorPhoto())) {
                r.setDoorPhotos(Arrays.stream(r.getDoorPhoto().split(",")).collect(Collectors.toList()));
            } else {
                r.setDoorPhotos(new ArrayList<>());
            }

            if (ObjectUtil.isNotEmpty(r.getEvnPhoto())) {
                r.setEvnPhotos(Arrays.stream(r.getEvnPhoto().split(",")).collect(Collectors.toList()));
            } else {
                r.setEvnPhotos(new ArrayList<>());
            }

            if (ObjectUtil.isNotEmpty(r.getDouyinPhoto())) {
                r.setDouyinPhotos(Arrays.stream(r.getDouyinPhoto().split(",")).collect(Collectors.toList()));
            } else {
                r.setDouyinPhotos(new ArrayList<>());
            }
        });
        return ret;
    }

    @Override
    public Integer countPage(ParamReq<RetailShopRequest> params) {
        return retailShopMapper.countPage(params);
    }

    @CacheEvict(value = "RETAIL_SHOP_POI_ID")
    @Override
    public Integer updateDelFlagById(Long id, Integer delFlag) {
        return retailShopMapper.updateDelFlagById(id, delFlag);
    }

    @Cacheable(value = "RETAIL_SHOP_POI_ID", key = "#poiId")
    @Override
    public RetailShopVo getmodelByPoiIdAndSource(String poiId, Integer shopSource) {
        return retailShopMapper.getmodelByPoiIdAndSource(poiId, shopSource);
    }

    @Override
    public List<RetailShopVo> findOwnerShopByAdminId(String adminId) {
        List<RetailShopVo> res = retailShopMapper.findOwnerShopByAdminId(adminId);
        res.forEach(r -> {
            r.setShopSourceName(ShopSourceEnums.getStatusValues(r.getShopSource()));
            r.setExamineVerifyName(ExamineVerifyEnums.getStatusValues(r.getExamineVerify()));
        });

        return res;
    }

    @Override
    public List<RetailShopVo> findOwnerShopByAdminIdAndId(String adminId) {
        List<RetailShopVo> res = retailShopMapper.findOwnerShopByAdminIdAndId(adminId);
        res.forEach(r -> {
            r.setShopSourceName(ShopSourceEnums.getStatusValues(r.getShopSource()));
            r.setExamineVerifyName(ExamineVerifyEnums.getStatusValues(r.getExamineVerify()));
        });

        return res;
    }

    @Override
    public List<RetailShopVo> myShopList(String adminId, String search) {
        List<RetailShopVo> res = retailShopMapper.myShopList(adminId, search);
        res.forEach(r -> {
            r.setShopSourceName(ShopSourceEnums.getStatusValues(r.getShopSource()));
            r.setExamineVerifyName(ExamineVerifyEnums.getStatusValues(r.getExamineVerify()));
        });

        return res;
    }

    @Override
    public RetailShopVo getModelByPoiIdLimmit1(String poiId) {
        RetailShopVo retailShopVo = retailShopMapper.getModelByPoiIdLimmit1(poiId);
        if (ObjectUtil.isNotEmpty(retailShopVo)) {
            retailShopVo.setExamineVerifyName(ExamineVerifyEnums.getStatusValues(retailShopVo.getExamineVerify()));
            retailShopVo.setShopSourceName(ShopSourceEnums.getStatusValues(retailShopVo.getShopSource()));
        }

        return retailShopVo;
    }

    @Override
    public List<RetailShopVo> toBeBindShop() {
        return retailShopMapper.toBeBindShop();
    }

    @Autowired
    private ShopCardMapper shopCardMapper;

    @Override
    public RetailShopVo findShopByShopId(Long shopId) {
        return retailShopMapper.findShopByShopId(shopId);
    }

    @Override
    public RetailShopVo getOwnerShopByOwnerId(Long ownerId) {
        RetailShopVo retailShopVo = retailShopMapper.getOwnerShopByOwnerId(ownerId);
        if (ObjectUtil.isNotEmpty(retailShopVo) && ObjectUtil.isNotEmpty(retailShopVo.getCardType())) {
            ShopCardVo scv = shopCardMapper.getModel(retailShopVo.getCardType());
            if (ObjectUtil.isNotEmpty(scv)) {
                retailShopVo.setCardTypeName(scv.getCardName());
            }
        }

        return retailShopVo;
    }

    @Override
    public List<RetailShopVo> getOfflineAllShopList(String search, String city) {
        return retailShopMapper.getOfflineAllShopList(search, city);
    }

    @Override
    public Result<RetailShopVo> getShopByOwnerId(Long ownerId) {
        RetailShopVo shop = retailShopMapper.getShopByOwnerId(ownerId);
        if (ObjectUtil.isEmpty(shop)) {
            shop = new RetailShopVo();
        }
        return Result.success(shop);
    }

    /**
     * 保存或者修改数据
     *
     * @param request
     * @return
     */
    @Override
    public Result<Integer> insertOrUpdateRetailShop(RetailShopRequest request) {
        Long count = 0L;
        if (ObjectUtil.isNotEmpty(request.getId())) {
            count = this.update(request);
        } else {
            request.setStatusFlag(StatusFlagEnum.USE.getValue());
            request.setDelFlag(DelFlagEnum.NO.getValue());
            count = this.save(request);
        }
        return Result.success(count);
    }

    @Override
    public List<ShopTypeStasticVo> getShopMonthStastics(Long adminId, String startTimestamp, String endTimestamp) {
        return retailShopMapper.getShopMonthStastics(adminId, startTimestamp, endTimestamp);
    }

    @Transactional
    @Override
    public Result<Integer> updateShopBelong(RetailShopRequest request) {
        Integer count = retailAdminShopMapper.deleteByShopId(request.getId());

        RetailAdminShopRequest req = new RetailAdminShopRequest();
        req.setAdminId(request.getAdminId());
        req.setShopId(request.getId());
        req.setExamineVerify(ExamineVerifyEnums.EXAMINE_VERIFIED.getValue());
        req.setStatusFlag(StatusFlagEnum.USE.getValue());
        req.setDelFlag(DelFlagEnum.NO.getValue());
        req.setCreateUser(1L);

        Long scount = retailAdminShopMapper.save(req);
        return Result.success(scount);
    }

    @Resource
    private AccessTokenService accessTokenService;

    @Resource
    private TokTikAppParamRequest tokTikAppParamRequest;

    @Override
    public List<RetailShopRequest> syncTokTikShopList(Integer page, Integer size) {
        String accessToken = accessTokenService.createTikTokAccessToken();
        String content = null;
        if (ObjectUtil.isNotEmpty(accessToken)) {
            content = requestDouyinShopResContent(accessToken, page, size);
        }
        if (ObjectUtil.isNotEmpty(content)) {
            return shopResToShopModel(content);
        } else {
            return new ArrayList<>();
        }
    }

    @Override
    public List<RetailShopVo> findAllShopByShopSource(Integer shopSource) {
        return retailShopMapper.findAllShopByShopSource(ShopSourceEnums.DY_TYPE.getValue());
    }

    @Override
    public Integer allShops() {
        return retailShopMapper.allShops();
    }

    @Override
    public Result<Integer> updatecityBelong(RetailShopRequest request) {
        Integer count =  retailShopMapper.updatecityBelong(request.getIds(), request.getCity());
        return Result.success(count);
    }

    private String requestDouyinShopResContent(String accessToken, Integer page, Integer size) {
        try {
            String url = tokTikAppParamRequest.getShopClientUrl()
                    + "?account_id=" + tokTikAppParamRequest.getAccountId()
                    + "&page=" + page
                    + "&size=" + size;
            OkHttpClient client = new OkHttpClient().newBuilder().build();
            Request request = new Request.Builder()
                    .url(url)
                    .addHeader("access-token", accessToken)
                    .get()
                    .build();
            Response response = client.newCall(request).execute();
            String content = response.body().string();
            response.close();
            return content;
        } catch (Exception e) {
            return null;
        }
    }

    public List<RetailShopRequest> shopResToShopModel(String content) {
        JSONObject jsonObject = JSONObject.parseObject(content);
        JSONObject data = jsonObject.getJSONObject("data");
        if (data.containsKey("error_code") && ObjectUtil.notEqual(data.getInteger("error_code"),0)) {
            accessTokenService.removeTikTokAccessToken();
            return new ArrayList<>();
        }
        List<RetailShopRequest> res = new ArrayList<>();
        if (data.containsKey("total") && data.containsKey("pois")) {
            Integer total = data.getInteger("total");
            if (total <= 0) {
                return res;
            }
            JSONArray pois = data.getJSONArray("pois");
            pois.stream().forEach(poio -> {
                JSONObject poiJ = (JSONObject) poio;
//            JSONObject rootAccount = poiJ.getJSONObject("root_account");
                JSONObject account = poiJ.getJSONObject("account");
                JSONObject parentAccount = account.getJSONObject("parent_account");
                JSONObject poiAccount = account.getJSONObject("poi_account");
                JSONObject poi = poiJ.getJSONObject("poi");
                RetailShopRequest request = new RetailShopRequest();
                request.setShopSource(ShopSourceEnums.DY_TYPE.getValue());
                request.setPoiId(poi.getString("poi_id"));
                request.setPoiName(poi.getString("poi_name"));
                request.setAddress(poi.getString("address"));
                request.setLatitude(poi.getBigDecimal("latitude").toString());
                request.setLongitude(poi.getBigDecimal("longitude").toString());
                request.setAccountId(poiAccount.getString("account_id"));
                request.setAccountName(poiAccount.getString("account_name"));
                request.setAccountType(poiAccount.getString("account_type"));
                request.setParentAccountId(parentAccount.getString("account_id"));
                request.setParentAccountName(parentAccount.getString("account_name"));

                request.setDelFlag(DelFlagEnum.NO.getValue());
                request.setStatusFlag(StatusFlagEnum.USE.getValue());
                request.setCreateUser(0L);
                request.setRemark(poio.toString());

                if (ObjectUtil.isNotEmpty(request) && ObjectUtil.isNotEmpty(request.getPoiId())) {
                    res.add(request);
                }
            });
            return res;
        }

        return new ArrayList<>();
    }
}
